<template>
  <div class="basic-page" :class="needHeight ? (isTabPage ? 'tabPage' : 'normalPage') : ''">
    <div class="ces-search">
      <el-form ref="searchData" inline :model="searchData">
        <el-form-item v-for="item in searchForm" :key="item.prop" :label="item.label" :prop="item.prop">
          <!-- 输入框 -->
          <el-input v-if="item.type==='Input'" v-model="searchData[item.prop]" />
          <el-input-number v-if="item.type==='InputNumber'" v-model="searchData[item.prop]" controls-position="right" :max="item.max" :min="item.min" />
          <!-- 下拉框 -->
          <el-select v-if="item.type==='Select'" v-model="searchData[item.prop]" clearable filterable>
            <el-option v-for="op in item.options" :key="op.value" :label="op.name" :value="op.value" />
          </el-select>
          <!--          级联-->
          <el-cascader
            v-if="item.type==='Cascader'"
            v-model="searchData[item.prop]"
            filterable
            :options="item.options"
            :show-all-levels="false"
            :props="{ checkStrictly: true, value: 'id', label: 'title',emitPath: false }"
            clearable
          />
          <!-- 单选 -->
          <el-radio-group v-if="item.type==='Radio'" v-model="searchData[item.prop]">
            <el-radio v-for="ra in item.radios" :key="ra.value" :label="ra.value">{{ ra.label }}</el-radio>
          </el-radio-group>
          <!-- 单选按钮 -->
          <el-radio-group v-if="item.type==='RadioButton'" v-model="searchData[item.prop]">
            <el-radio-button v-for="ra in item.radios" :key="ra.value" :label="ra.value">{{ ra.label }}</el-radio-button>
          </el-radio-group>
          <!-- 复选框 -->
          <el-checkbox-group v-if="item.type==='Checkbox'" v-model="searchData[item.prop]">
            <el-checkbox v-for="ch in item.checkboxs" :key="ch.value" :label="ch.value">{{ ch.label }}</el-checkbox>
          </el-checkbox-group>
          <!-- 日期 -->
          <el-date-picker v-if="item.type==='Date'" v-model="searchData[item.prop]" :type="item.dateType" :value-format="item.valueFormat ? item.valueFormat : 'timestamp'" />
          <!-- 时间 -->
          <el-time-select v-if="item.type==='Time'" v-model="searchData[item.prop]" type="" />
          <!-- 日期时间 -->
          <el-date-picker v-if="item.type==='DateTime'" v-model="searchData[item.prop]" type="datetime" :disabled="item.disable && item.disable(searchData[item.prop])" />
          <!-- 滑块 -->
          <!-- <el-slider v-if="item.type==='Slider'" v-model="searchData[item.prop]"></el-slider> -->
          <!-- 开关 -->
          <el-switch v-if="item.type==='Switch'" v-model="searchData[item.prop]" />
        </el-form-item>
        <el-form-item v-if="searchForm.length>0">
          <el-button type="primary" @click="filterList()"> <i class="el-icon-search" /> 查询</el-button>
        </el-form-item>
        <el-form-item v-if="searchForm.length>0">
          <el-button type="primary" @click="handleReset()"> <i class="el-icon-refresh-right" /> 重置</el-button>
        </el-form-item>
        <el-form-item v-if="exportApi" v-permission="'export'">
          <el-button type="warning" @click="handleDownload()"> <i class="el-icon-download" /> 导出</el-button>
        </el-form-item>
        <el-form-item v-if="draggable">
          <el-button type="primary" @click="handleOrder()"> <i class="el-icon-s-grid" /> 保存排序</el-button>
        </el-form-item>
        <el-form-item v-for="item in searchHandle" :key="item.label" v-permission="item.permission">
          <el-button :type="item.type" @click="item.handle()"> <i :class="item.icon" /> {{ item.label }}</el-button>
        </el-form-item>
      </el-form>
    </div>
    <vxe-toolbar size="medium" custom :refresh="{query: getList}">
      <template v-slot:tools>
        <div v-if="isTreeData">
          <el-tooltip :content="isOpening ?'展开全部':'关闭全部'" placement="bottom" effect="light">
            <el-button style="margin-right: 10px" :icon="isOpening ?'el-icon-caret-top':'el-icon-caret-bottom'" circle @click="showOpening" />
          </el-tooltip>
        </div>
      </template>
    </vxe-toolbar>
    <vxe-table
      ref="xTree"
      size="medium"
      row-id="id"
      border
      resizable
      auto-resize
      highlight-hover-row
      :data="tableData"
      :loading="listLoading"
      :max-height="tableHeight"
      :header-cell-style="{
        'background-color': '#d9ecfe',
        'color': '#333',
        'border-bottom': '1px #dbdbdb solid'
      }"
      :tree-config="{children: 'children', iconOpen: 'el-icon-caret-bottom', iconClose: 'el-icon-caret-right', reserve:true}"
      :edit-config="{trigger: 'click', mode: 'row', showStatus: true}"
      :expand-config="{accordion: true, lazy: true, loadMethod: loadContentMethod, reserve:true}"
      :edit-rules="validRules"
      keep-source
      :cell-class-name="cellClassName"
      @header-row-class-name="handleTableClass"
      @checkbox-change="handleSelectionChange"
      @checkbox-all="handleSelectionChange"
    >
      <vxe-table-column v-if="draggable" width="40">
        <template #default>
          <span class="drag-btn">
            <i class="vxe-icon--menu" />
          </span>
        </template>
        <template #header>
          <vxe-tooltip v-model="showHelpTip1" content="按住后可以上下拖动排序！" enterable>
            <i class="vxe-icon--question" @click="showHelpTip1 = !showHelpTip1" />
          </vxe-tooltip>
        </template>
      </vxe-table-column>
      <template v-for="(item, index) in columns">
        <vxe-table-column v-if="!item.type" :key="index" v-bind.sync="item['config']" :class-name="item.className ? item.className: ''" />
        <vxe-table-column v-else-if="item.type === 'selection'" :key="index" type="checkbox" width="40" />
        <vxe-table-column v-else-if="item.type === 'time'" :key="index" v-bind.sync="item['config']">
          <template slot-scope="scope">
            {{ parseTime(scope.row, item.config.field) }}
          </template>
        </vxe-table-column>
        <vxe-table-column v-else-if="item.type === 'copy'" :key="index" v-bind.sync="item['config']" :class-name="item.className ? item.className: ''">
          <template slot-scope="scope">
            <span style="display: inline-block" @click="handleDetail(scope.row, item)">{{ scope.row[item.config.field] }}</span>
            <el-tooltip class="item" effect="dark" content="复制" placement="top">
              <i v-clipboard:copy="scope.row[item.config.field]" v-clipboard:success="clipboardSuccess" class="el-icon-copy-document" />
            </el-tooltip>
          </template>
        </vxe-table-column>
        <vxe-table-column v-else-if="item.type === 'tree'" :key="index" v-bind.sync="item['config']" tree-node :class-name="item.className ? item.className: ''">
          <template v-slot="{ row }">
            <span>
              <template v-if="(row.children && row.children.length) || row.parentId === '0'">
                <i :class="$refs.xTree.isTreeExpandByRow(row) ? 'co-icon-zg-folder-opened-fill' : 'co-icon-folder_opened'" />
              </template>
              <template v-else>
                <i class="el-icon-document" />
              </template>
              <span style="display: inline-block" @click="handleDetail(row, item)">{{ row[item.config.field] }}</span>
              <el-tooltip class="item" effect="dark" content="复制" placement="top">
                <i v-clipboard:copy="row[item.config.field]" v-clipboard:success="clipboardSuccess" class="el-icon-copy-document" />
              </el-tooltip>
            </span>
          </template>
        </vxe-table-column>
        <vxe-table-column v-else-if="item.type === 'filter'" :key="index" v-bind.sync="item['config']" :class-name="item.className ? item.className: ''">
          <template v-slot="{ row }">
            <span :class="row[item.config.field] | filterClassColor(item.option)" :style="row[item.config.field] | filterColor(item.option)">
              {{ row[item.config.field] | filterType(item.option) }}
            </span>
          </template>
        </vxe-table-column>
        <vxe-table-column v-else-if="item.type === 'edit' && item.editType === 'date'" :key="index" v-bind.sync="item['config']" :edit-render="item.editRender">
          <template slot-scope="scope">
            <span style="display: inline-block">{{ scope.row[item.config.field] | filterTime('YYYY-MM-DD') }}</span>
          </template>
        </vxe-table-column>
        <vxe-table-column v-else-if="item.type === 'edit'" :key="index" v-bind.sync="item['config']" :edit-render="item.editRender" />
        <vxe-table-column v-else-if="item.type === 'status'" :key="index" v-bind.sync="item['config']">
          <template v-slot="{ row }">
            <el-switch v-model="row[item.config.field]" disabled />
          </template>
        </vxe-table-column>
        <vxe-table-column v-else-if="item.type === 'format'" :key="index" v-bind.sync="item['config']" :formatter="item.formatter" />
        <vxe-table-column v-else :key="index" v-bind.sync="item['config']" :class-name="item.className ? item.className: ''">
          <template slot-scope="scope">
            <expand-item :colum="item" :row="scope.row" :render="item.render" />
          </template>
        </vxe-table-column>
      </template>
    </vxe-table>
    <div v-if="showPagination" class="block">
      <el-pagination
        :page-sizes="[10, 20, 30, 50]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        :current-page="searchData.currentPage"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        @prev-click="handleCurrentChange"
        @next-click="handleCurrentChange"
      />
    </div>
  </div>
</template>

<script>
import clipboard from '@/directive/clipboard' // use clipboard by v-directive
import * as list from '@/api/getTableList'
import moment from 'moment'
import { saveAs } from 'file-saver'
import checkPermission from '@/utils/permission'
import Sortable from 'sortablejs'

export default {
  name: '',
  directives: {
    clipboard
  },
  components: {
    expandItem: {
      functional: true,
      props: {
        row: Object,
        render: Function,
        column: {
          type: Object,
          default: null
        }
      },
      render: (h, ctx) => {
        const params = {
          row: ctx.props.row
        }
        if (ctx.props.column) params.column = ctx.props.column
        return ctx.props.render(h, params)
      }
    }
  },
  props: {
    showPagination: {
      type: Boolean,
      default: true
    },
    showTitle: {
      type: Boolean,
      default: true
    },
    columns: {
      required: true,
      type: Array,
      default: () => {
        return []
      }
    },
    size: {
      type: String,
      default: ''
    },
    searchOtherData: {
      type: Object,
      default: () => {
        return {}
      }
    },
    searchForm: {
      type: Array,
      default: () => {
        return []
      }
    },
    searchHandle: {
      type: Array,
      default: () => []
    },
    listApi: {
      type: String,
      default: ''
    },
    delApi: {
      type: String,
      default: ''
    },
    exportApi: {
      type: String,
      default: ''
    },
    exportName: {
      type: String,
      default: '表格'
    },
    isTreeData: {
      type: Boolean,
      default: false
    },
    isAuto: {
      type: Boolean,
      default: true
    },
    draggable: {
      type: Boolean,
      default: false
    },
    validRules: {
      type: Object,
      default: () => {
        return {}
      }
    },
    needHeight: {
      type: Boolean,
      default: true
    },
    isTabPage: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      tableData: [],
      listLoading: false,
      isOpening: true,
      total: 0,
      searchData: {
        currentPage: 1,
        pageSize: 10
      },
      tableHeight: '1329px',
      showHelpTip1: false
    }
  },
  watch: {
    searchForm: {
      handler: function(newValue) {
        newValue.forEach((item) => {
          if (item.type === 'Date' && item.dateType === 'year') {
            const year = moment().year().toString()
            console.log(moment(year).format('x'))
            if (item.valueFormat) {
              this.$set(this.searchData, item.prop, moment(year).format('yyyy'))
            } else {
              this.$set(this.searchData, item.prop, moment(year).format('x'))
            }
            // this.searchData[item.prop] = moment(year).format('x')
          }
        })
      },
      deep: true,
      immediate: true
    }
  },
  created() {
    if (this.isAuto) {
      this.getList()
    }
    if (this.draggable) {
      this.rowDrop()
    }
    this.tableHeight = (document.body.clientHeight - 450) + 'px'
  },
  beforeDestroy() {
    if (this.sortable1) {
      this.sortable1.destroy()
    }
  },
  methods: {
    rowDrop() {
      this.$nextTick(() => {
        const xTable = this.$refs.xTree
        this.sortable1 = Sortable.create(xTable.$el.querySelector('.body--wrapper>.vxe-table--body tbody'), {
          handle: '.drag-btn',
          onEnd: ({ newIndex, oldIndex }) => {
            const currRow = this.tableData.splice(oldIndex, 1)[0]
            this.tableData.splice(newIndex, 0, currRow)
          }
        })
      })
    },
    handleOrder() {
      console.log(this.tableData)
      let index = 0
      const arr = this.tableData.map((item) => {
        index++
        item.displayOrder = index
        return item
      })
      console.log(arr)
      this.$emit('saveDragOrder', arr)
    },
    handleDetail(row, item) {
      const type = item.permission ? item.permission : 'details'
      if (item.className && checkPermission(type)) {
        this.$emit('handleDetail', row)
      }
    },
    handleTableClass() {
      return 'tableHeader'
    },
    clipboardSuccess() {
      this.$message({
        message: '复制成功',
        type: 'success',
        duration: 1500
      })
    },
    parseTime(row, field) {
      const arr = field.split('.')
      if (arr.length === 1) {
        if (row[field]) {
          return moment(row[field]).format('YYYY-MM-DD HH:mm:ss')
        } else {
          return ''
        }
      } else {
        if (row[arr[0]][arr[1]]) {
          return moment(row[arr[0]][arr[1]]).format('YYYY-MM-DD HH:mm:ss')
        } else {
          return ''
        }
      }
    },
    showOpening() {
      this.isOpening ? this.$refs.xTree.setAllTreeExpand(true) : this.$refs.xTree.clearTreeExpand()
      this.isOpening = !this.isOpening
    },
    // 查询
    filterList() {
      this.searchData.currentPage = 1
      this.getList()
    },
    // 重置
    handleReset() {
      this.searchData.currentPage = 1
      this.$refs['searchData'].resetFields()
      this.getList()
    },
    // pagination start
    handleSizeChange(pageSize) {
      this.searchData.pageSize = pageSize
      this.getList()
    },
    handleCurrentChange(currentPage) {
      this.searchData.currentPage = currentPage
      this.getList()
    },
    // pagination end
    getList() {
      this.listLoading = true
      this.searchData = Object.assign(this.searchData, this.searchOtherData)
      list[this.listApi](this.searchData).then(response => {
        if (Array.isArray(response.data)) {
          this.tableData = response.data
        } else {
          if (response.data.list) {
            this.tableData = response.data.list
          } else {
            this.tableData = []
          }
          this.total = response.data.pagination.total
          this.searchData.currentPage = response.data.pagination.current
        }
        this.listLoading = false
      }).catch(() => {
        this.listLoading = false
      })
    },
    handleDownload() {
      const formData = new FormData()
      for (const k in this.searchData) {
        formData.append(k, this.searchData[k])
      }
      list[this.exportApi](formData).then(response => {
        saveAs(response, this.exportName + '.xlsx')
      })
    },
    handleSelectionChange(val) {
      console.log(val)
      this.$emit('selectionChange', val.records)
    },
    handleDelete(row) {
      this.$confirm('此操作将永久删除, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        const loading = this.$loading({
          lock: true,
          text: '删除中',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        })
        list[this.delApi](row.id).then(response => {
          this.$notify({
            title: '成功',
            message: '删除成功',
            type: 'success',
            duration: 2000
          })
          loading.close()
          this.getList()
        }).catch(() => {
          loading.close()
        })
      }).catch(() => {
        this.$notify({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    getUpdateData() {
      const $table = this.$refs.xTree
      const { updateRecords } = $table.getRecordset()
      return updateRecords
    },
    revertData() {
      const $table = this.$refs.xTree
      $table.revertData()
    },
    async validEvent() {
      const $table = this.$refs.xTree
      const errMap = await $table.validate().catch(errMap => errMap)
      if (errMap) {
        this.$message({ message: '数据校验不通过', type: 'warning' })
        return false
      } else {
        return true
      }
    },
    loadContentMethod({ row }) {
      return new Promise(resolve => {
        const api = this.columns[0].expandApi
        list[api]({ id: row.id }).then(response => {
          console.log(response)
          row.childData = response.data[0].list
          resolve()
        }).catch(() => {
          row.childData = []
          resolve()
        })
      })
    },
    cellClassName({ row, rowIndex, column, columnIndex }) {
      switch (column.property) {
        case 'warninfoBefOil':
        case 'warninfoBefWater':
        case 'warninfoBefLiq':
          return 'col-light-yellow'
        case 'warninfoCurrOil':
        case 'warninfoCurrWater':
        case 'warninfoCurrLiq':
          return 'col-light-blue'
      }
    }
  }
}
</script>

<style scoped>
.basic-page{
  padding: 20px;
  background: #fff;
  border-radius: 5px;
  overflow: auto;
  width: 100%;
}
.tabPage{
  height: calc(100vh - 290px);
}
.normalPage{
  height: calc(100vh - 210px);
}
.ces-search {
  display: flex;
  align-items: center;
}
.block{
  margin-top: 40px;
  text-align: center;
}
.el-icon-copy-document{
  /*color: #0984ff;*/
  color: #333333;
  cursor: pointer;
  margin-left: 10px;
}
.co-icon-zg-folder-opened-fill, .co-icon-folder_opened{
  color: #f5d672;
  margin-right: 10px;
  font-size: 20px;
}
.el-icon-document{
  margin-right: 10px;
  font-size: 20px;
}
.swpuLink{
  cursor: pointer;
}
</style>
